package com.wpre.lotterysystem.service.activitystatus.impl;

import com.wpre.lotterysystem.common.errcode.ServiceErrorCodeConstants;
import com.wpre.lotterysystem.common.exception.ServiceException;
import com.wpre.lotterysystem.service.ActivityService;
import com.wpre.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.wpre.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.wpre.lotterysystem.service.dto.ConvertActivityStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: LianBao
 * Date: 2024-12-24
 * Time: 19:57
 */
@Service
@Slf4j
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Autowired
    private ActivityService activityService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //问题:活动扭转状态有依赖性,活动状态需要根据奖品状态来判断,并且扭转状态条件可能会扩展,当前写法维护性差
        //解决方案:设计模式:责任链模式+策略模式

        if (CollectionUtils.isEmpty(operatorMap)) {
            log.warn("当前operatorMap为空");
        }

        Map<String, AbstractActivityOperator> currentMap = new HashMap<>(operatorMap);

        Boolean isUpdate = false;

        //1.先处理:人员、奖品
        isUpdate = processConvertStatus(convertActivityStatusDTO, currentMap, 1);

        //2.后处理:活动

        isUpdate = processConvertStatus(convertActivityStatusDTO, currentMap, 2) || isUpdate;
//        if (isUpdate) {
//            processConvertStatus(convertActivityStatusDTO, currentMap, 2);
//        } else {
//            isUpdate = processConvertStatus(convertActivityStatusDTO, currentMap, 2);
//        }
        //3.更新缓存
        if (isUpdate) {
            //更新缓存
            activityService.cacheUpdateActivity(convertActivityStatusDTO.getActivityId());
        }

    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {

        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }
        //缓存更新
        activityService.cacheUpdateActivity(convertActivityStatusDTO.getActivityId());
    }

    //扭转状态
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currentMap,
                                         int sequence) {
        Boolean update = false;
        //遍历currentMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currentMap.entrySet().iterator();

        while (iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            if (operator.sequence() != sequence ||
                    !operator.needConvert(convertActivityStatusDTO)) {
                //不需要转换
                continue;
            } else {
                //需要转换
                Boolean convert = operator.convert(convertActivityStatusDTO);

                if (!convert) {
                    log.error("processConvertStatus {} 转换失败", operator.getClass().getName());
                    throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_CONVERT_ERROR);
                }
            }
            iterator.remove();//从map中删除
            update = true;
        }

        return update;

    }
}
